<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf8">
    <!--

    @license twgl.js Copyright (c) 2015, Gregg Tavares All Rights Reserved.
    Available via the MIT license.
    see: http://github.com/greggman/twgl.js for details

    -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
    <meta property="og:title" content="TWGL.js - simple-packed-arrays" />
    <meta property="og:type" content="website" />
    <meta property="og:image" content="http://twgljs.org/examples/screenshots/simple-packed-arrays.png" />
    <meta property="og:description" content="TWGL.js - simple-packed-arrays" />
    <meta property="og:url" content="http://twgljs.org" />

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@greggman">
    <meta name="twitter:creator" content="@greggman">
    <meta name="twitter:domain" content="twgljs.org">
    <meta name="twitter:title" content="TWGL.js - simple-packed-arrays">
    <meta name="twitter:url" content="http://twgljs.org/examples/simple-packed-arrays.html">
    <meta name="twitter:description" content="TWGL.js - simple-packed-arrays">
    <meta name="twitter:image:src" content="http://twgljs.org/examples/screenshots/simple-packed-arrays.png">

    <link href="/resources/images/twgljs-icon.png" rel="shortcut icon" type="image/png">

    <title>twgl.js - simple-packed-arrays</title>
    <style>
      body {
          margin: 0;
          font-family: monospace;
      }
      canvas {
          display: block;
          width: 100vw;
          height: 100vh;
      }
      #b {
        position: absolute;
        top: 10px;
        width: 100%;
        text-align: center;
        z-index: 2;
      }
    </style>
  </head>
  <body>
    <canvas id="c"></canvas>
    <div id="b"><a href="http://twgljs.org">twgl.js</a> - simple-packed-arrays</div>
  </body>
  <script id="vs" type="notjs">
attribute vec4 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec2 v_texcoord;
varying vec4 v_color;

void main() {
  v_texcoord = a_texcoord;
  v_color = a_color;
  gl_Position = a_position;
}
  </script>
  <script id="fs" type="notjs">
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texcoord;
varying vec4 v_color;

void main() {
  gl_FragColor = texture2D(u_texture, v_texcoord) * v_color;
}
 </script>
  <script type="module">
    import * as twgl from '../dist/4.x/twgl-full.module.js';
    const gl = document.querySelector("#c").getContext("webgl");
    const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

    const typedArrayWithPackedData = makePackedData();  // eslint-disable-line

    const packedBuffer = twgl.createBufferFromTypedArray(
        gl, typedArrayWithPackedData);

    const typedArrayWithIndices = new Uint16Array([0, 1, 2, 2, 1, 3]);
    const indexBuffer = twgl.createBufferFromTypedArray(
        gl, typedArrayWithIndices, gl.ELEMENT_ARRAY_BUFFER);

    const stride = 24;
    const handMadeBufferInfo = {
      numElements: 6, // or whatever
      indices: indexBuffer,            // remove if no indices
      elementType: gl.UNSIGNED_SHORT,  // remove if no indices
      attribs: {
        a_position: { buffer: packedBuffer, numComponents: 3, type: gl.FLOAT,         stride: stride, offset:  0, },
        a_texcoord: { buffer: packedBuffer, numComponents: 2, type: gl.FLOAT,         stride: stride, offset: 12, },
        a_color:    { buffer: packedBuffer, numComponents: 4, type: gl.UNSIGNED_BYTE, stride: stride, offset: 20, normalize: true, },
      },
    };

    const uniforms = {
      u_texture: twgl.createTexture(gl, { src: makeCircleCanvas }),  // eslint-disable-line
    };

    twgl.resizeCanvasToDisplaySize(gl.canvas);
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.useProgram(programInfo.program);
    twgl.setBuffersAndAttributes(gl, programInfo, handMadeBufferInfo);
    twgl.setUniforms(programInfo, uniforms);
    twgl.drawBufferInfo(gl, handMadeBufferInfo);

    function makeCircleCanvas() {
      // make a texture with a circle in it
      const canvas2d = document.createElement("canvas");
      canvas2d.width = 64;
      canvas2d.height = 64;
      const ctx = canvas2d.getContext("2d");
      ctx.fillStyle = "#fff";
      ctx.beginPath();
      ctx.arc(32, 32, 30, 0, Math.PI * 2, false);
      ctx.fill();

      return canvas2d;
    }

    function makePackedData() {
      // there's no easy way to interleave the data unless we use pure binary so
      // lets do it manually.
      const position = [
        -1, -1, 0,
         1, -1, 0,
        -1,  1, 0,
         1,  1, 0,
      ];
      const texcoord = [
         0,  0,
         1,  0,
         0,  1,
         1,  1,
      ];
      const color = [
         255, 0, 0, 255,
         0, 255, 0, 255,
         0, 0, 255, 255,
         255, 255, 255, 255,
      ];

      const stride = 24; // position + texcoord + rgba8

      const typedArrayWithPackedData = new ArrayBuffer(stride * 4);
      const floatView = new Float32Array(typedArrayWithPackedData);
      const uint8View = new Uint8Array(typedArrayWithPackedData);
      const floatAdd = 1;
      const uint8Add = stride - 4;
      let floatOffset = 0;
      let uint8Offset = stride - 4;
      let positionOffset = 0;
      let texcoordOffset = 0;
      let colorOffset = 0;
      for (let ii = 0; ii < 4; ++ii) {
        floatView[floatOffset++] = position[positionOffset++];
        floatView[floatOffset++] = position[positionOffset++];
        floatView[floatOffset++] = position[positionOffset++];
        floatView[floatOffset++] = texcoord[texcoordOffset++];
        floatView[floatOffset++] = texcoord[texcoordOffset++];
        floatOffset += floatAdd;
        uint8View[uint8Offset++] = color[colorOffset++];
        uint8View[uint8Offset++] = color[colorOffset++];
        uint8View[uint8Offset++] = color[colorOffset++];
        uint8View[uint8Offset++] = color[colorOffset++];
        uint8Offset += uint8Add;
      }
      return typedArrayWithPackedData;
    }

  </script>
</html>



